#!/usr/bin/env python


import os
import sys
import time
sys.path.insert(0,'/home/mike/python')

import re
from flickrapi import FlickrAPI


flickrAPIKey = ""
flickrSecret = ""
fapi = None

BASE = '/home/mike/projects/albertarandonneurs.ca/content'
OUTPUT = '/home/mike/projects/albertarandonneurs.ca/html'
IGNORE = ['menu.html', 'schedule.htm', 'redirect-template.html', 'photos', 'gps', 'brevet']
IGNORE.append('report--july-4-2008--hell-week.html')
IGNORE_ENDINGS = ['css', 'jpeg']

EQUIV = {
#    'knowledge-base.html':['preparation.html','definitions.html','safety.html','results.html','reports.html','links.html','maps.html']
         }

#	<li><a href="ride-schedule.html">2008 Ride Calendar</a></li>

menuopen = re.compile('.*(\\<!--MENU--\\>).*')
menuclose = re.compile('.*(\\<!--/MENU--\\>).*')
menunamematch = re.compile('.*a href="(.*?)".*')
menusplitter = re.compile('\\<li')
submenusplitter = re.compile('\\</li\\>')
flickr = re.compile('.*\\<flickrphoto\\>(.*?)\\</flickrphoto\\>.*')
localphoto = re.compile('.*\\<localphoto caption="(.*)"\\>(.*?)\\</localphoto\\>.*')
googledoc = re.compile('.*\\<googledoc\\>(.*?)\\</googledoc\\>.*')
resultdoc = re.compile('.*\\<resultdoc name="(.*?)"\\>(.*?)\\</resultdoc\\>.*')
rideschedule = re.compile('.*\\<rideschedule year="(.*?)"\\>(.*?)\\</rideschedule\\>.*')
googledocBodyOpen = re.compile('.*id="doc-contents".*')
#googledocBodyClose = re.compile('.*\\</div\\>.*')
googledocBodyClose = re.compile('.*\\<div id="google-view-footer"\\>.*')

menu = open(os.path.join(BASE,'menu.html'),'r').readlines()

RIDE_SCHEDULES = {'2010': 'http://spreadsheets.google.com/pub?key=tj8CZwlnMqEs4_HaTLGY5ew&single=true&gid=0&output=csv'}
RIDE_SCHEDULES['2010'] = 'file:///home/mike/projects/albertarandonneurs.ca/pub?key=tj8CZwlnMqEs4_HaTLGY5ew&single=true&gid=0&output=csv'

ridelist = {}

from urllib import urlopen
import csv

def rideScheduleCsvToRideList(rawdata, year):
    """
    this method returns a list of tuples, with each tuple being:

    (date, ridelength, region, organizername, organizeremail, ridename, rideurl)

    ...and sorted by date.
    """
    
    reader = csv.reader(rawdata)
    reader.next()                       # should be top header line
    ridetype = reader.next()            # should explain which ride is what
    ## first skip until we find some text
    ridecolumns = []
    idx = 0
    while ridetype[0] == '':
        ridetype = ridetype[1:]
        idx += 1
    ## now, each header we have is a ride-type (e.g. "200", "300")
    ## and so we record the index at which they start
    while len(ridetype):
        if len(ridetype[0]):
#            if len(ridecolumns):
#                ridecolumns[-1] = ridecolumns[-1] + (idx,)
            ridecolumns.append( (idx, ridetype[0]) )
        ridetype = ridetype[1:]
        idx += 1

    rides = []
    for line in reader:
        if len(line) == 0:
            continue
        ## usually the "ride" lines start with "Canada"
        if line[0].lower() != 'canada':
            #print "skipping:",line
            continue

        if len(line) < 5:
            print "weird line:",line
            continue

        (name,email) = (line[3],line[4])
        region = line[1]
        region = region.split('-')[1].strip()
        region = region.lower()
        
        if len(line) < ridecolumns[0][0]:
            print "No rides for",name,email,len(line),ridecolumns
        else:
            idx = ridecolumns[0][0]
            for date in line[idx:]:
                if len(date) > 0:
                    ridetype = None
                    for (col,ridename) in ridecolumns:
                        if idx >= col:
                            ridetype = ridename
                    rides.append( (date.strip() + ', ' + year, ridetype, region, name, email,'', '') )
                    
                idx += 1

    def sorter(a,b):
        return cmp(time.strptime(a[0], "%d-%b, %Y"), time.strptime(b[0], "%d-%b, %Y"))
    rides.sort(sorter)
    return rides

#    print "RIDES:"
#    print "date\t\tlength\tregion\t\torganizer"
#    print "-"*80
#    for r in rides:
#        print "%s\t\t%s\t%s\t\t%s (%s)" % r[0:5]

        
    if 0:
        """
        lines look like:
        Canada,Alberta Randonneurs - Calgary,011921,Ken Myhre,kmyhre@telus.net,,10-Apr,17-Apr,1-May,24-Apr,8-May,11-Sep,22-May

        ..and the dates are in groups of 3: first 200, then 300, then
        400, then 600, then one column for fleche and one for 1000.
        Starting at column 5 (0-based, so 6th column)
        """

def rideListToHtml(ridelist, region=None):
    if region:
        ridelist = filter(lambda x: x[2] == region, ridelist)

    rtn = '''
    <table>
	<tr>
	    <th width="26%" style="text-align:left;">Name/Distance (km)</th>
	    <th width="7%">Date</th>
	    <th width="25%">Location</th>
	    <th width="12%">Time</th>
	    <th width="15%">Route</th>
	    <th width="15%">Organizer</th>
	</tr>
    '''
    
    for item in ridelist:
        ht = {}
        ht['done'] = ''                 # fixme
        ht['ridename'] = item[5]
        if item[5] == '':
            try:
                ht['ridename'] = str(int(item[1])) + 'km'
            except:
                ht['ridename'] = item[1]
        ht['url'] = item[6]
        ht['linktext'] = ''
        ht['email'] = ' dot '.join('(aT]'.join(item[4].split('@')).split('.'))
        ht['organizer'] = item[3]
        ht['length'] = item[1]
        ht['date'] = time.strftime("%B %d", time.strptime(item[0], "%d-%b, %Y"))
        ht['meetpoint'] = ''
        ht['starttime'] = ''
        
###<td><a href="%(url)s">%(ridename)s</a></td>
      
        rtn = rtn + '''
    <tr%(done)s>
      <td style="text-align:left;">%(ridename)s</td>
      <td>%(date)s</td>
      <td>%(meetpoint)s</td>
      <td>%(starttime)s</td>
      <td><!--URL goes here--></td>
      <td><a href="mailto:%(email)s">%(organizer)s</a></td>
    </tr>''' % ht
    
    return rtn + '</table>'


def resultdocToHtml(rawdata,url,name):
    rtn = '''
    <table style="width:100%;">
      <tr>
	<th style="width:25%;">Homologation #</th>
	<th style="width:35%;">Last Name</th>
	<th style="width:25%;">First Name</th>
	<th style="width:15%;">Time</th>
      </tr>
'''
    lineTemplate = '      <tr%(odd)s>\n	<td>%(homologation)d</td>\n	<td>%(last)s</td>\n	<td>%(first)s</td>\n	<td>%(time)s</td>\n      </tr>\n'

    valid = []
    found = False
    matcher = re.compile('^,,.*$')
    for line in rawdata:
        print line
        if len(line.strip()) == 0:
            if found:
                break
            valid = []
            found = False
            continue
        
        if matcher.match(line):
            if name.lower().strip() in line.lower().strip():
                found = name
                #print "  FOUND",name
                continue

        if not found:
            continue
        
        try:
            values = line.strip().split(',')
            #print "VALUES:",values
            if len(values) == 7:
                (hom,last,first,club,sex,cityhom,time) = values
                hom = int(hom.strip())
                valid.append({'homologation': hom,
                              'last': last,
                              'first': first,
                              'club': club,
                              'cityhomologation':cityhom,
                              'time': time
                              })
        except:
            print line
            return '<p><b>Processing Error</b>: on <a href="%s">google-doc</a>.</p>' % url

    if len(valid) == 0:
        print "Can't find:",name,"in",url
        return '<p><b>Processing Error</b>: no "%s" in <a href="%s">google-doc</a>.</p>' % (name,url)
    
    valid.sort(lambda a,b: cmp(a['last'],b['last']))
    odd = False
    for values in valid:
        oddstr = ' class="odd"'
        if not odd:
            oddstr = ''
        odd = not odd
        values['odd'] = oddstr
        rtn = rtn + lineTemplate % values


    rtn = rtn + '''    </table>\n\n'''

    rtn = rtn + '<p class="small">From <a href="%s">google-doc</a>.</p>' % (url.split('&')[0])
    
    return rtn


def googledocToHtml(rawdata):
    data = ''
    take = False
    ILLEGAL = ['br']
    for line in rawdata:
        if googledocBodyOpen.match(line):
            take = True
            continue
        if googledocBodyClose.match(line):
            take = False
            continue
        if take:
            data = data + line

    rtn = ''
    tag = None
    cnt = ''
    def foundtag(tag):
        tag = tag.strip().lower()
        if tag in ILLEGAL or tag.split()[0] in ILLEGAL:
            return ''
        rtn = '<' + tag.split()[0]
        for bit in tag.split()[1:]:
            if 'href' == bit[:4]:
                rtn = rtn + ' ' + bit
        return rtn + '>'
    
    for c in data:
        if c == '<':
            if len(cnt):
                rtn = rtn + cnt
                cnt = ''
            tag = ''
        elif c == '>':
            rtn = rtn + foundtag(tag)
            tag = None

        else:
            if tag is not None:
                tag = tag + c
            else:
                cnt = cnt + c
        
    return rtn

if 'test' in sys.argv:
    print rideScheduleCsvToRideList(open('pub?key=tj8CZwlnMqEs4_HaTLGY5ew&single=true&gid=0&output=csv','r').readlines(), '2010')
    #print resultdocToHtml(open('pub?key=r6Jslx3IhjGcw3wlDbASCfA&single=true&gid=3&output=csv','r').readlines(), 'testing', 'fairmont')
    #print resultdocToHtml(open('pub?key=rb_CYdrc6Ld1gaJowbrd2wQ&single=true&gid=0&output=csv','r').readlines(), 'testing', 'francis')
    #print resultdocToHtml(open('pub?key=pRsK-nSzsveu1Zy7LedTvPw&output=csv','r').readlines(), 'testing', 'strathmore')
    #print googledocToHtml(open('View?docid=ddnn83bk_10ftjhvz43','r').readlines())
    sys.exit(0)

def remap(line):
    if flickr.match(line):
        global fapi, token
        if fapi is None:
            fapi = FlickrAPI(flickrAPIKey, flickrSecret)
            token = fapi.getToken(browser="lynx")

        id = flickr.match(line).group(1)
        print "  talking to Flickr about: ",id
        
        rsp = fapi.photos_getInfo(api_key=flickrAPIKey,auth_token=token,photo_id=id)
        fapi.testFailure(rsp)
        description = rsp.photo[0].description[0].elementText
        URL = rsp.photo[0].urls[0].url[0].elementText

        rsp = fapi.photos_getSizes(api_key=flickrAPIKey,auth_token=token,photo_id=id)
        fapi.testFailure(rsp)
        for x in rsp.sizes[0].size:
            #if x.attrib['label'] == 'Square':
            if x.attrib['label'] == 'Small':
                return '<a href="%(url)s"><img src="%(src)s" height="%(height)s" width="%(width)s" alt="%(alt)s" /></a>' % \
                       {'src':x.attrib['source'],
                        'height':x.attrib['height'],
                        'width':x.attrib['width'],
                        'url':URL,
                        'alt':description}

    elif localphoto.match(line):
        m = localphoto.match(line)
        caption = m.group(1)
        id = m.group(2)
        thumb = id.split('.')[0] + '-thumb.jpeg'
        if not os.path.exists(thumb):
            cmd = 'convert -resize 240x240 ' + os.path.join(BASE,'photos/'+id) + ' ' + os.path.join(BASE,'photos/'+thumb)
            print cmd
            os.system(cmd)

        ## FIXME size probably wrong
        return '<a href="/photos/%s"><img src="/photos/%s" height="180" width="240" alt="%s" /></a>' % (id, thumb, caption)
    

    elif googledoc.match(line):
        url = googledoc.match(line).group(1)
        print "  talking to Google about:",url
        html = googledocToHtml(urlopen(url).readlines())
        return html
                
    elif resultdoc.match(line):
        name = resultdoc.match(line).group(1)
        url = resultdoc.match(line).group(2)
        print "  talking to Google about results:",url
        html = resultdocToHtml(urlopen(url).readlines(), url, name)
        return html
                
    elif rideschedule.match(line):
        year = rideschedule.match(line).group(1).strip()
        region = rideschedule.match(line).group(2).strip().lower()
        if not year in ridelist.keys():
            print "  talking to Google about schedule:",year,region
            ridelist[year] = rideScheduleCsvToRideList(urlopen(RIDE_SCHEDULES[year]).readlines(), '2010')
            
        html = rideListToHtml(ridelist[year], region)
        return html
                
    return line
                           

        

def menuActivateLine(line):
    m = menusplitter.search(line)
    before = line[:m.end()]
    after = line[m.end():]

    return before + ' class="active"' + after

def menuActive(line,x):
    m = menunamematch.match(line)
    if not m:
        return False
    
    if m.group(1) == x:
        return True
    if EQUIV.has_key(m.group(1)):
        if x in EQUIV[m.group(1)]:
            return True
    if x[:8] == 'report--' and (m.group(1) == 'knowledge-base.html' or m.group(1) == 'reports.html'):
        return True
    if x[:6] == 'maps--' and m.group(1) == 'knowledge-base.html':
        return True
        
    return False
        
def menuInsertSubmenu(line,submenu):
    rtn = menuActivateLine(line)
    m = submenusplitter.search(rtn)
    return rtn[:m.start()] + submenu + rtn[m.start():]

filelist = os.listdir(BASE)
if len(sys.argv) > 1 and not 'test' in sys.argv:
    filelist = sys.argv[1:]
for x in filelist:
    if x[-1] == '~':
        continue
    if x[-3:] in IGNORE_ENDINGS or x[-4:] in IGNORE_ENDINGS:
        continue
    if x in IGNORE:
        continue

    print x
    
    path = os.path.join(BASE,x)
    data = open(path,'r').readlines()
    menuopenidx = None
    menucloseidx = None
    for idx in range(0,len(data)):
        line = data[idx]
        if menuopen.match(line):
            menuopenidx = idx
        elif menuclose.match(line):
            menucloseidx = idx

    if menuopenidx and not menucloseidx:
        file = open(os.path.join(OUTPUT,x),'w')
        for idx in range(0,len(data)):
            if idx == menuopenidx:
                for line in menu:
                    if menuActive(line,x):
                        file.write(menuActivateLine(line))
                    else:
                        file.write(line)
            else:
                file.write(remap(data[idx]))
        file.close()
    elif menuopenidx and menucloseidx:
        myitem = None
        idx = -1
        for line in menu:
            if menuActive(line,x):
                myitem = idx
            idx = idx + 1
        if idx < 0:
            raise "Can't find menu item for %s" % x
        file = open(os.path.join(OUTPUT,x),'w')
        submenu = ''
        for idx in range(0,len(data)):
            if idx >= menuopenidx and idx < menucloseidx:
                submenu = submenu + data[idx]
            elif idx == menucloseidx:
                for line in menu:
                    if menuActive(line,x):
                        file.write(menuInsertSubmenu(line,submenu))
                    else:
                        file.write(line)
            else:
                file.write(remap(data[idx]))
        file.close()
    else:
        raise "Cannot proceeed; no menu for %s."%x
        
        
        
